/*
 * Copyright 2007 - The JDPF Project Team (http://www.jdpf.org) 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package org.jdpf.core.plugins.parameters;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.keyvalue.MultiKey;
import org.apache.commons.collections.map.MultiKeyMap;
import org.jdpf.core.plugins.datatypes.AbstractDataType;

/**
 * In JDPF the parameters are sent in the component in the same way
 * of real data. Thus, they are implemented as an extension of the
 * abstract data type class and lately embedded in a token.
 * 
 * The map of the parameters is implemented with multiple keys: the
 * plugin id and the parameter name. This way every plugin knows which
 * are the parameters it has to load.
 */
public class Parameters extends AbstractDataType {

	private final MultiKeyMap map;
	
	public Parameters(){
		map=new MultiKeyMap();
	}
	
	/**
	 * @see org.jdpf.core.plugins.datatypes.AbstractDataType#getValue()
	 */
	@Override
	public Object getValue() {
		return map;
	}
	
	/**
	 * This method returns the list of plugin's id that have some parameters set
	 *  
	 * @return The plugin id list
	 */
	public List<String> getPluginIdList(){
		List<String> pluginIdKeys = new ArrayList<String>(10);
		Iterator i = map.keySet().iterator();
		while(i.hasNext()){
			MultiKey keys = (MultiKey)i.next();
			String transIdKey = (String)keys.getKey(0);
			if(!pluginIdKeys.contains(transIdKey)){
				pluginIdKeys.add(transIdKey);	
			}
		}
		return pluginIdKeys;
	}
	
	/**Return the value associated with the given parameter name for specific 
	 * plugin.
	 * @param idPlugin - the Plugin the value refers to.
	 * @param paramName - the parameter name the value refers to.
	 * @return The values of the parameter.
	 */
	public Object getParameterValue(String idPlugin,String paramName){
		return map.get(idPlugin, paramName);
	}
	
	/**
	 * Returns the desired parameter value in the desired data type format.
	 * @param idPlugin	The <code>id</code>of the plugin
	 * @param paramName	The parameter name
	 * @param typeToReturn		The datatype to be returned
	 * @return	The parameter value in the requested data type.
	 * @throws IOException 
	 */
	public Object getParameterValue(String idPlugin,String paramName, 
			ParametersTypesEnum parameterType) throws IOException{
		Object toConvert = map.get(idPlugin, paramName);
		Object toReturn = null;
		if (parameterType.equals(ParametersTypesEnum.Int)) {
			toReturn= Integer.parseInt((String) toConvert);
		} else if (parameterType.equals(ParametersTypesEnum.Float)) {
			toReturn = Float.parseFloat((String) toConvert);
		} else if (parameterType.equals(ParametersTypesEnum.Double)) {
			toReturn = Double.parseDouble((String) toConvert);
		} else if (parameterType.equals(ParametersTypesEnum.Boolean)) {
			toReturn = Boolean.parseBoolean((String) toConvert);
		} else if (parameterType.equals(ParametersTypesEnum.String)) {
			toReturn = toConvert;
		} else if (parameterType.equals(ParametersTypesEnum.URI)) {
			toReturn = URI.create(((String) toConvert).replace(" ", "%20"));
		}  
		
		return toReturn;
	}
	
	/**Add a new parameter refered to a specific plugin
	 * @param idPlugin - the <code>id</code> of the plugin this parameter refers
	 *  to.
	 * @param paramName - the name of this parameter.
	 * @param value - the real value associated to the parameter.
	 */
	public void setParameterValue(String idPlugin,String paramName,Object value){
		map.put(idPlugin,paramName, value);
	}
	
	/**Return a list of all parameters that refers to a specific plugin.
	 * @param idPlugin - The specific plugin
	 * @return The list of parameters reported to the specific plugin.
	 */
	public List<String> getParameterNames(String idPlugin){
		List<String> list=new ArrayList<String>(10);
		Set set=map.keySet();
		Iterator i=set.iterator();
		while(i.hasNext()){
			MultiKey m=(MultiKey)i.next();
			if(m.getKey(0).equals(idPlugin)){
				String name=(String) m.getKey(1);
				list.add(name);
			}
		}
		return list;
	}
}
